import pymysql
from movie_dao import MovieDAO
import logging
import jieba
import re
from collections import Counter

logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)

class WordCloudDAO:
    """词云数据访问对象，用于处理电影简介的词云分析"""
    
    def __init__(self):
        """初始化词云DAO对象"""
        self.movie_dao = MovieDAO()
        # 定义停用词列表，这些词在分词时会被过滤掉
        self.stop_words = {
            '的', '了', '和', '是', '就', '都', '而', '及', '与', '这', '那', '有', '在',
            '中', '为', '以', '到', '说', '对', '能', '等', '着', '个', '也', '但', '还',
            '要', '去', '把', '让', '被', '给', '从', '向', '于', '由', '它', '她', '他',
            '我', '你', '们', '或', '并', '很', '又', '只', '没', '不', '可', '如', '若',
            '所', '其', '已', '因', '使', '得', '着', '之', '乎', '则', '且', '但', '而',
            '何', '乃', '于', '焉', '也', '矣', '以', '于', '之', '则', '者', '着', '自',
            '暂无简介', '简介', '暂无', '电影', '影片', '剧情', '故事', '讲述', '讲述的是',
            '讲述了一个', '讲述了', '讲述的', '讲述', '讲述着', '讲述过', '讲述着', '讲述着',
            '讲述着', '讲述着', '讲述着', '讲述着', '讲述着', '讲述着', '讲述着', '讲述着'
        }  # 包含常见虚词、语气词和电影领域特定词汇

    def get_word_cloud_data(self):
        """获取词云数据的主方法"""
        conn = None
        cursor = None
        try:
            logger.info("开始连接数据库获取词云数据")
            conn = self.movie_dao.get_connection()
            cursor = conn.cursor(pymysql.cursors.DictCursor)

            # SQL查询：获取所有非空且非"暂无简介"的电影简介
            sql = """
                SELECT intro 
                FROM movies 
                WHERE intro IS NOT NULL 
                  AND intro != ''
                  AND intro != '暂无简介'
            """
            logger.info("执行SQL查询获取电影简介")
            cursor.execute(sql)
            introductions = cursor.fetchall()
            logger.info(f"获取到 {len(introductions)} 条电影简介")
            
            # 调试信息：打印前三条简介
            if introductions:
                logger.info("前3条简介示例:")
                for i, intro in enumerate(introductions[:3]):
                    logger.info(f"简介 {i+1}: {intro['intro'][:100]}...")

            if not introductions:
                logger.warning("没有获取到有效的电影简介数据")
                return []

            # 数据处理：合并所有简介文本
            all_text = ' '.join([item['intro'] for item in introductions])
            logger.info(f"合并后的文本长度: {len(all_text)}")
            logger.info(f"合并后文本前100个字符: {all_text[:100]}")
            
            # 文本清理
            cleaned_text = self._clean_text(all_text)
            logger.info(f"清理后的文本长度: {len(cleaned_text)}")
            logger.info(f"清理后文本前100个字符: {cleaned_text[:100]}")
            
            # 中文分词
            words = self._segment_words(cleaned_text)
            logger.info(f"分词后得到 {len(words)} 个词")
            if words:
                logger.info(f"分词示例(前10个): {words[:10]}")
            
            # 统计词频
            word_freq = self._count_word_frequency(words)
            logger.info(f"统计得到 {len(word_freq)} 个高频词")
            if word_freq:
                logger.info(f"词频统计示例(前5个): {dict(list(word_freq.items())[:5])}")
            
            # 转换数据格式：将词频数据转换为前端所需的格式
            word_cloud_data = [
                {'name': word, 'value': count}
                for word, count in word_freq.items()
            ]

            logger.info(f"生成词云数据: {word_cloud_data[:5]} ... 共{len(word_cloud_data)}个词")
            return word_cloud_data

        except Exception as e:
            logger.error(f"获取词云数据时出错: {str(e)}")
            logger.exception("详细错误信息:")
            return []
        finally:
            if cursor:
                cursor.close()
            if conn:
                conn.close()

    def _clean_text(self, text):
        """清理文本，去除特殊字符、数字和多余空格"""
        # 移除特殊字符和标点符号
        text = re.sub(r'[^\w\s]', '', text)
        # 移除数字
        text = re.sub(r'\d+', '', text)
        # 移除多余空格
        text = re.sub(r'\s+', ' ', text)
        logger.info(f"文本清理前长度: {len(text)}")
        cleaned = text.strip()
        logger.info(f"文本清理后长度: {len(cleaned)}")
        return cleaned

    def _segment_words(self, text):
        """使用结巴分词对文本进行分词处理"""
        # 使用jieba进行中文分词
        words = jieba.cut(text)
        # 过滤停用词和单字词
        filtered_words = [
            word for word in words 
            if word not in self.stop_words 
            and len(word) > 1
        ]
        logger.info(f"分词前停用词数量: {len(self.stop_words)}")
        logger.info(f"分词后得到词数: {len(filtered_words)}")
        return filtered_words

    def _count_word_frequency(self, words):
        """统计词频并返回前100个高频词"""
        # 使用Counter统计词频
        word_freq = Counter(words)
        # 只保留词频大于1的词
        word_freq = {word: count for word, count in word_freq.items() if count > 1}
        # 按词频降序排序
        sorted_word_freq = dict(sorted(word_freq.items(), key=lambda x: x[1], reverse=True))
        # 只返回前100个高频词
        result = dict(list(sorted_word_freq.items())[:100])
        logger.info(f"词频统计结果数量: {len(result)}")
        return result 